const cloud = require("wx-server-sdk");
const { PDFDocument, rgb, PDFName } = require("pdf-lib");
const axios = require("axios");

cloud.init({ env: process.env.WX_CLOUD_ENV || cloud.DYNAMIC_CURRENT_ENV });

/**
 * 选择性清理 XObject 水印：仅移除高复用且疑似水印的对象，保留签名/章等内容。
 * - 不删除 Annots（避免移除签章）
 * - 仅在名称包含 Watermark/WM/Stamp 等且在多数页面复用的情况下清除
 * @param {PDFDocument} pdfDoc
 * @param {import('pdf-lib').PDFPage[]} pages
 * @param {{mode?: 'safe'|'aggressive'}} opts
 */
function cleanSelectiveWatermarks(pdfDoc, pages, opts = {}) {
  const mode = opts.mode || 'safe'
  // 统计各页面 XObject 键命中频次
  const freq = new Map()
  const pageKeys = []
  pages.forEach((page) => {
    const keys = []
    try {
      const resVal = page.node.get(PDFName.of('Resources'))
      const resDict = resVal ? pdfDoc.context.lookup(resVal) : null
      if (resDict && typeof resDict.get === 'function') {
        const xobjVal = resDict.get(PDFName.of('XObject'))
        const xobjDict = xobjVal ? pdfDoc.context.lookup(xobjVal) : null
        if (xobjDict && typeof xobjDict.keys === 'function') {
          xobjDict.keys().forEach((k) => {
            const name = String(k)
            keys.push(k)
            freq.set(name, (freq.get(name) || 0) + 1)
          })
        }
      }
    } catch (_) {}
    pageKeys.push(keys)
  })

  const threshold = mode === 'aggressive' ? Math.max(2, Math.floor(pages.length * 0.4)) : Math.max(2, Math.floor(pages.length * 0.7))
  const keysToDeleteNames = new Set()
  freq.forEach((count, name) => {
    if (count >= threshold && /(Watermark|WM|Stamp|Background|Bg|DRAFT|CONFIDENTIAL)/i.test(name)) {
      keysToDeleteNames.add(name)
    }
  })

  // 仅删除命中 keys，保留其他资源
  pages.forEach((page) => {
    try {
      const resVal = page.node.get(PDFName.of('Resources'))
      const resDict = resVal ? pdfDoc.context.lookup(resVal) : null
      if (resDict && typeof resDict.get === 'function') {
        const xobjVal = resDict.get(PDFName.of('XObject'))
        const xobjDict = xobjVal ? pdfDoc.context.lookup(xobjVal) : null
        if (xobjDict && typeof xobjDict.keys === 'function') {
          xobjDict.keys().forEach((k) => {
            const name = String(k)
            if (keysToDeleteNames.has(name)) {
              try { xobjDict.delete(k) } catch (_) {}
            }
          })
        }
      }
    } catch (_) {}
  })
}

/**
 * 通过第三方水印移除服务处理 PDF
 * - 读取环境变量 `PDF_WM_API_URL` 与可选的 `PDF_WM_API_KEY`
 * - 以 `application/pdf` 直接 POST 原始字节，期待返回处理后的 PDF 字节
 * @param {Uint8Array|Buffer} bytes 原始 PDF 字节
 * @returns {Promise<Buffer|null>} 处理后的 PDF 字节；失败返回 null
 */
async function removeWatermarkViaApi(bytes) {
  const endpoint = process.env.PDF_WM_API_URL;
  const apiKey = process.env.PDF_WM_API_KEY;
  if (!endpoint) return null;
  try {
    const res = await axios.post(endpoint, bytes, {
      headers: {
        "Content-Type": "application/pdf",
        ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
      },
      responseType: "arraybuffer",
      timeout: 30000,
    });
    if (res && res.status >= 200 && res.status < 300 && res.data) {
      return Buffer.from(res.data);
    }
    return null;
  } catch (_) {
    return null;
  }
}

/**
 * 去除水印云函数入口
 * - 输入：
 *   - event.fileID: 云存储 PDF 文件ID（cloud:// 开头）
 *   - event.coverRects: 可选，遮盖矩形数组 [{ x, y, width, height }]
 * - 处理：
 *   - 清理注释、OCG、疑似水印的 XObject
 *   - 按需绘制遮盖矩形
 * - 输出：
 *   - { ok: true, fileID } 或 { ok: false, error }
 */
exports.main = async (event, context) => {
  const { fileID, coverRects = [], mode = 'safe', preserveAnnots = true } = event || {};
  if (!fileID) {
    return { ok: false, error: "missing fileID" };
  }
  try {
    // 下载原始PDF
    const dlRes = await cloud.downloadFile({ fileID });
    console.log("download file res:", dlRes);
    const bytes = dlRes.fileContent || dlRes.data;

    // 载入PDF
    let buffer = await removeWatermarkViaApi(bytes);
    if (!buffer) {
      const pdfDoc = await PDFDocument.load(bytes);
      const pages = pdfDoc.getPages();
      // 选择性清理，避免误删签章/手写
      cleanSelectiveWatermarks(pdfDoc, pages, { mode });
      // OCG 仅在名称明显标识水印时清理
      try {
        const ocProps = pdfDoc.catalog.get(PDFName.of('OCProperties'))
        const ocDict = ocProps ? pdfDoc.context.lookup(ocProps) : null
        if (ocDict && typeof ocDict.get === 'function') {
          const ocgsVal = ocDict.get(PDFName.of('OCGs'))
          const arr = ocgsVal ? pdfDoc.context.lookup(ocgsVal) : null
          if (arr && typeof arr.asArray === 'function') {
            const items = arr.asArray()
            const keep = []
            items.forEach((ref) => {
              try {
                const g = pdfDoc.context.lookup(ref)
                const name = g && g.get && g.get(PDFName.of('Name'))
                const nStr = name ? String(pdfDoc.context.lookup(name)) : ''
                if (!/(Watermark|WM|Stamp)/i.test(nStr)) keep.push(ref)
              } catch (_) { keep.push(ref) }
            })
            if (keep.length === items.length) {
              // 没有命中水印命名则保留
            } else {
              try { ocDict.set(PDFName.of('OCGs'), arr.constructor.fromArray(keep, pdfDoc.context)) } catch (_) {}
            }
          }
        }
      } catch (_) {}
      if (Array.isArray(coverRects) && coverRects.length > 0) {
        pages.forEach((page) => {
          coverRects.forEach((r) => {
            const { x = 0, y = 0, width = 0, height = 0 } = r || {};
            if (width > 0 && height > 0) {
              page.drawRectangle({ x, y, width, height, color: rgb(1, 1, 1) });
            }
          });
        });
      }
      const outBytes = await pdfDoc.save();
      buffer = Buffer.from(outBytes);
    }

    // 生成保存路径
    const ts = Date.now();
    const cloudPath = `pdfs/clean/${ts}-clean.pdf`;

    const upRes = await cloud.uploadFile({ cloudPath, fileContent: buffer });
    return { ok: true, fileID: upRes.fileID };
  } catch (e) {
    return { ok: false, error: String((e && e.message) || e) };
  }
};
